package cn.net.dckj.modules.pay.web;

import cn.net.dckj.common.pay.common.HttpKit;
import cn.net.dckj.common.pay.common.IpKit;
import cn.net.dckj.common.pay.common.PaymentKit;
import cn.net.dckj.common.pay.common.ZxingKit;
import cn.net.dckj.common.pay.wx.api.WxPayApi;
import cn.net.dckj.common.pay.wx.api.WxPayApi.TradeType;
import cn.net.dckj.common.pay.wx.api.WxPayApiConfig;
import cn.net.dckj.common.pay.wx.api.WxPayApiConfig.PayModel;
import cn.net.dckj.common.pay.wx.api.WxPayApiConfigKit;
import cn.net.dckj.common.pay.wx.api.WxPayApiController;
import cn.net.dckj.common.pay.wx.model.WxPayConfig;
import cn.net.dckj.common.persistence.JsonData;
import cn.net.dckj.common.utils.StringUtils;
import cn.net.dckj.modules.biz.entity.BizEcsOrder;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping(value = "${adminPath}/pay/wxPay")
public class WxPayController extends WxPayApiController {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    private JsonData jsonData = new JsonData();

    @Autowired
    WxPayConfig wxPayConfig;

    // 通知地址，异步接收微信支付结果通知的回调地址，通知url必须为外网可访问的url，不能携带参数。
    String notify_url;

    @Override
    public WxPayApiConfig getApiConfig() {
        notify_url = wxPayConfig.getDomain().concat(adminPath + "/pay/wxPay/pay_notify");
        return WxPayApiConfig.New()
                .setAppId(wxPayConfig.getAppId())
                .setMchId(wxPayConfig.getMchId())
                .setPaternerKey(wxPayConfig.getPartnerKey())
                .setPayModel(PayModel.BUSINESSMODEL);
    }

    /**
     * Native支付，该模式适用于PC网站等
     * 扫码支付模式二
     */
    @RequestMapping(value = "/scanCode2", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public JsonData scanCode2(BizEcsOrder bizEcsOrder, HttpServletRequest request, HttpServletResponse response) {
        // 商品简单描述，必填，该字段请按照规范传递，如PC网站规则：浏览器打开的网站主页title名 -商品概述
        String body = bizEcsOrder.getMealName() + bizEcsOrder.getRemarks();
        // 附加数据，选填，在查询API和支付通知中原样返回，可作为自定义参数使用
        String attach = "微信扫码支付模式二";
        // 商户订单号，必填，商户系统内部订单号，要求32个字符内，只能是数字、大小写字母_-|* 且在同一个商户号下唯一
        String outTradeNo = bizEcsOrder.getId();
        // 标价金额，必填，订单总金额，单位为分
        long mealPrice = Math.round(bizEcsOrder.getMealPrice() * 100);
        String totalFee = String.valueOf(mealPrice);
        if (StringUtils.isBlank(totalFee)) {
            jsonData.setSuccess(false).setMessage("支付金额不能为空");
            return jsonData;
        }
        // 终端IP，必填，支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP
        String ip = IpKit.getRealIp(request);
        if (StringUtils.isBlank(ip)) {
            ip = "127.0.0.1";
        }
        // 商品ID，trade_type=NATIVE时，此参数必传。此参数为二维码中包含的商品ID，商户自行定义
        String productId = bizEcsOrder.getSetMealId();
        /*// 用户标识，trade_type=JSAPI时（即JSAPI支付），此参数必传，此参数为微信用户在商户对应appid下的唯一标识
        String openId = (String) request.getSession().getAttribute("openId");
        //openId="o5NJx1dVRilQI6uUVSaBDuLnM3iM";
        if (StringUtils.isBlank(openId)) {
            jsonData.setSuccess(false).setMessage("openId is null");
            return jsonData;
        }*/

        // 统一下单
        Map<String, String> params = WxPayApiConfigKit.getWxPayApiConfig()
                .setBody(body)
                .setAttach(attach)
                .setOutTradeNo(outTradeNo)
                .setTotalFee(totalFee)
                .setSpbillCreateIp(ip)
                .setNotifyUrl(notify_url)
                .setTradeType(TradeType.NATIVE)
                .setProductId(productId)
                .build();
        String xmlResult = WxPayApi.pushOrder(true, params);
        log.info(xmlResult);
        System.out.println(xmlResult);

        Map<String, String> resultMap = PaymentKit.xmlToMap(xmlResult);
        String returnCode = resultMap.get("return_code");
        String returnMsg = resultMap.get("return_msg");
        if (!PaymentKit.codeIsOK(returnCode)) {
            jsonData.setSuccess(false).setMessage("error:" + returnMsg);
            return jsonData;
        }
        String resultCode = resultMap.get("result_code");
        if (!PaymentKit.codeIsOK(resultCode)) {
            jsonData.setSuccess(false).setMessage("error:" + returnMsg);
            return jsonData;
        }

        //生成预付订单success
        String qrCodeUrl = resultMap.get("code_url");
        String name = "payQRCode2.png";

        Boolean encode = ZxingKit.encode(qrCodeUrl, BarcodeFormat.QR_CODE, 3, ErrorCorrectionLevel.H, "png", 200, 200,
                request.getServletContext().getRealPath("/") + File.separator + name);
        if (encode) {
            //renderQrCode(qrCodeUrl, 200, 200);
            //在页面上显示
            jsonData.setSuccess(true).setData(name);
            return jsonData;
        }
        return null;
    }

    @RequestMapping(value = "/pay_notify", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public String pay_notify(HttpServletRequest request) {
        // 支付结果通用通知文档: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7

        String xmlMsg = HttpKit.readData(request);
        System.out.println("支付通知=" + xmlMsg);
        Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);
//		String appid  = params.get("appid");
//		//商户号
//		String mch_id  = params.get("mch_id");
        String result_code = params.get("result_code");
//		String openId      = params.get("openid");
//		//交易类型
//		String trade_type      = params.get("trade_type");
//		//付款银行
//		String bank_type      = params.get("bank_type");
//		// 总金额
//		String total_fee     = params.get("total_fee");
//		//现金支付金额
//		String cash_fee     = params.get("cash_fee");
//		// 微信支付订单号
//		String transaction_id      = params.get("transaction_id");
//		// 商户订单号
//		String out_trade_no      = params.get("out_trade_no");
//		// 支付完成时间，格式为yyyyMMddHHmmss
//		String time_end      = params.get("time_end");

        /////////////////////////////以下是附加参数///////////////////////////////////

        String attach = params.get("attach");
//		String fee_type      = params.get("fee_type");
//		String is_subscribe      = params.get("is_subscribe");
//		String err_code      = params.get("err_code");
//		String err_code_des      = params.get("err_code_des");
        // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
        // 避免已经成功、关闭、退款的订单被再次更新
//		Order order = Order.dao.getOrderByTransactionId(transaction_id);
//		if (order==null) {
        if (PaymentKit.verifyNotify(params, WxPayApiConfigKit.getWxPayApiConfig().getPaternerKey())) {
            if (("SUCCESS").equals(result_code)) {
                //更新订单信息
                log.warn("更新订单信息:" + attach);
                //发送通知等
                Map<String, String> xml = new HashMap<String, String>();
                xml.put("return_code", "SUCCESS");
                xml.put("return_msg", "OK");
                return PaymentKit.toXml(xml);
            }
        }
//		}

        return null;
    }
}
